package com.goldgov.code.template.impl;

import java.util.List;
import java.util.Map;

import com.goldgov.code.meta.FieldInfo;
import com.goldgov.code.meta.ModuleInfo;
import com.goldgov.code.meta.RelationInfo;
import com.goldgov.code.meta.RelationInfo.RelationType;
import com.goldgov.code.template.Group;
import com.goldgov.code.template.Layout;
import com.goldgov.code.template.point.CodePoint;
import com.goldgov.code.template.point.PointMapping;
import com.goldgov.code.template.point.impl.ImportCodePoint;
import com.goldgov.code.template.point.impl.InterfaceMethodCodePoint;
import com.goldgov.code.template.point.impl.MyBatisResultMapAssociationCodePoint;
import com.goldgov.code.template.point.impl.MyBatisXmlCodePoint;
import com.goldgov.code.utils.PackageUtils;
import com.goldgov.code.utils.StringUtils;

public class DaoLayout implements Layout{

	public static final String PACKAGE_NAME = "dao";
	
	@Override
	public String packageName() {
		return PACKAGE_NAME;
	}

	@Override
	public String templatePath() {
		return PACKAGE_NAME;
	}

	@Override
	public Class<?>[] dependOn() {
		return new Class[] {BeanLayout.class};
	}

	@Override
	public PointMapping codePoint(String packageName,ModuleInfo moduleInfo,Group group,Map<String,Object> paramMap) {
		PointMapping pointMapping = new PointMapping();
		
		String modulePackageName = StringUtils.lowerFirstChar(moduleInfo.getPackageName());
		List<CodePoint> codePointList = pointMapping.codePoint("*/*Dao.java.ftl");
		codePointList.add(new ImportCodePoint(PackageUtils.joinPackageName(packageName,modulePackageName,BeanLayout.PACKAGE_NAME,moduleInfo.getName())));
		codePointList.add(new ImportCodePoint(PackageUtils.joinPackageName(packageName,modulePackageName,BeanLayout.PACKAGE_NAME,moduleInfo.getName() + "Query")));
		
		RelationInfo relation = moduleInfo.getRelation();
		if(relation != null && relation.getType() == RelationType.MANY_TO_ONE) {
			List<CodePoint> xmlPointList = pointMapping.codePoint("*/*Dao.xml.ftl");
			ModuleInfo relationModule = relation.getRelationModule();
			String parentName = relationModule.getName();
			String methodName= "get" + parentName + moduleInfo.getName();
			codePointList.add(new InterfaceMethodCodePoint(methodName, moduleInfo.getName(), "String " + StringUtils.lowerFirstChar(moduleInfo.getPkField().getName())));
			
			String pTable = StringUtils.getWordFirstChar(relationModule.getTableName());
			String sTable = StringUtils.getWordFirstChar(moduleInfo.getTableName());
			StringBuilder xmlBuilder = new StringBuilder();
			xmlBuilder.append("    <select id=\"" + methodName + "\" resultMap=\"" + StringUtils.lowerFirstChar(moduleInfo.getName()) + "\">\r\n");
			
			String fileds = getSelectFileds(pTable,relationModule.getFields(),null);
			fileds += "," + getSelectFileds(sTable,relationModule.getFields(),fileds.split(","));
			
			xmlBuilder.append("        SELECT " + fileds + " FROM " + relationModule.getTableName() + " " + pTable + ",");
			xmlBuilder.append(moduleInfo.getTableName() + " " + sTable);
			xmlBuilder.append(" WHERE " + pTable + "." + relationModule.getPkField().getField() + "=" + sTable + "." + relation.getRelationField() + "\r\n");
			xmlBuilder.append("    </select>");
			xmlPointList.add(new MyBatisXmlCodePoint(xmlBuilder.toString()));
			xmlPointList.add(new MyBatisResultMapAssociationCodePoint(packageName,relation.getRelationName(),relationModule));
		}
		
		return pointMapping;
	}
	
	private String getSelectFileds(String tableAlias,FieldInfo[] fields,String[] exclude) {
		if(fields == null || fields.length == 0) {
			return "";
		}
		StringBuilder fieldBuilder = new StringBuilder(tableAlias + "." + fields[0].getField());
		boolean skip;
		for (int i = 1; i < fields.length; i++) {
			FieldInfo fieldInfo = fields[i];
			skip = false;
			if(exclude != null) {
				for(String ex : exclude) {
					if(fieldInfo.getField().endsWith("." + ex.trim())) {
						skip = true;
					}
					
				}
			}
			
			if(!skip) {
				fieldBuilder.append("," + tableAlias + "." + fieldInfo.getField());
			}
		}
		return fieldBuilder.toString();
	}

	@Override
	public void init(ModuleInfo moduleInfo) {
		
	}

}
